package com.gmstu.springframework.aop;

import com.gmstu.springframework.aop.intercept.GpMethodInvocation;
import com.gmstu.springframework.aop.support.GpAdvisedSupport;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 * @author John.zhang
 * @version Id: GpJdkDynamicAopProxy, v 1.0 2020/8/26 16:45 ZhiYong Exp $
 */
public class GpJdkDynamicAopProxy implements GpAopProxy, InvocationHandler {

    private GpAdvisedSupport advised;

    public GpJdkDynamicAopProxy(GpAdvisedSupport advised) {
        this.advised = advised;
    }

    @Override
    public Object getProxy() {
        return getProxy(advised.getTargetClass().getClassLoader());
    }

    @Override
    public Object getProxy(ClassLoader classLoader) {
        return Proxy.newProxyInstance(classLoader, this.advised.getTargetClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        List<Object> interceptorsAndDynamicInterceptorAdvice = this.advised.getInterceptorsAndDynamicInterceptorAdvice(method, this.advised.getTargetClass());
        GpMethodInvocation methodInvocation = new GpMethodInvocation(proxy, this.advised.getTarget(), method, args, this.advised.getTargetClass(), interceptorsAndDynamicInterceptorAdvice);
        return methodInvocation.proceed();
    }
}
